/*
 * File:   main.cpp
 * Author: Kreyl
 *
 * Created on May 27, 2011, 6:37 PM
 */

#include "kl_lib.h"
#include "led.h"
#include "usb.h"

#include "periph.h"

Usb_t Usb;

// Prototypes
void GeneralInit(void);
void LedInit(void);

//void BulkRx(void);
//void InterruptRx(void);
uint8_t EpBuf[128];

// ==== LED's ====
LedSmooth_t PwrLed;

void UsbTask(void);
void LedTask(void);

// ============================ Implementation ================================
int main(void) {
    GeneralInit();
    // Led On
    PwrLed.SetSmoothly(50);
//    uint32_t Tmr;

    // ==== Main cycle ====
    while(1) {
        LedTask();
        UsbTask();
        CmdUnit.Task();

//        if(Delay.Elapsed(&Tmr, 999)) {
//            CmdUnit.Printf("%A\r", Rx.PBuf, 65);
//        }
        // Choose Task to do
        if(!Device.IsConfigured) Device.Config(Device.Type);

        switch (Device.Type) {
            case dtDefault:
                UsartPeriph.Task();
                break;
            case dtCOM_Port:
                UsartPeriph.Task();
                break;
            case dtSPI_Line:
                break;
            case dtI2C_Line:
                break;
        }
    } // while(1)
    return 0;
}

void GeneralInit(void) {
    // Configuration device as COM Port
    Device.Type = dtDefault;
    Device.IsConfigured = false;
    // Disable JTAG
    klJtagDisable();
    //System Clock
    SystemCoreClockUpdate();
    // Init peripheral
    Delay.Init();
    // Led's Init
    LedInit();
    // Init USART1 as debug uart PA9 - TX
    CmdUnit.Init(500000);

    Usb.Ep[3].Buf = EpBuf;
    Usb.Init();

    // wait for configure
    Usb.IConnect();

    CmdUnit.Printf("\rArmUsb\r");
}

void LedInit(){
    PwrLed.Init(GPIOB, 0, TIM3, 1000, 0, 3, false);
    RxLed.Init(GPIOB, 1);
    TxLed.Init(GPIOB, 2);
}
void LedTask() {
    TxLed.Task();
    RxLed.Task();
    PwrLed.Task();
}

void UsbTask() {
    if(Usb.Ep[3].NewPktReceived) {
//        klPrintf("Ep3: %H\r", Usb.Ep[3].Buf, Usb.Ep[3].Count);
        Usb.Ep[3].NewPktReceived = false;

//        UsartPeriph.Send(Usb.Ep[3].Buf[0]);           // Send straight to Periph FIXME
        for (uint32_t l=0; l<Usb.Ep[3].Count; l++) {    // Write all data to Tx.Buf
            BufToPeriph.Write(Usb.Ep[3].Buf[l]);
        }

//        Send data back - ECHO
//        Usb.Ep[1].Buf = Usb.Ep[3].Buf;
//        Usb.Ep[1].Count = Usb.Ep[3].Count;
//        Usb.Ep[1].WriteData();
//        Usb.Ep[1].SetTxState(epxValid);
    }
}

// ==================== Usb Wakeup & Suspend
void Usb_t::WakeUp() {
    *ISTR = CLR_WKUP;   // Clear Wake Up bit
    CmdUnit.Printf("WUP\r");
}

void Usb_t::Suspend() { // Clear Suspend bit
    *ISTR = CLR_SUSP;
    CmdUnit.Printf("SUS\r");
}


